use crate::common::packages::{PortRedirStatus, Role, SetGetRole};
use crate::common::quic::QuicConn;
use crate::proxy::config::{ProxyConfig, TcpPorts};
use crate::proxy::controlled::{ControlledInstance, PortRedirInstance};
use std::sync::{Arc, OnceLock};
use tokio::sync::RwLock;

pub mod client;
pub mod config;
pub mod controlled;

pub static GLOBAL_CFG: OnceLock<Arc<ProxyConfig>> = OnceLock::new();
pub static PORT_CONFIG: OnceLock<Option<Arc<RwLock<TcpPorts>>>> = OnceLock::new();

pub fn init(cfg: Arc<ProxyConfig>, port_cfg: Option<Arc<RwLock<TcpPorts>>>) {
    GLOBAL_CFG.get_or_init(|| cfg );
    PORT_CONFIG.get_or_init(|| port_cfg);
    controlled::init();
}

pub fn get_global_config() -> Arc<ProxyConfig> {
    GLOBAL_CFG.get().unwrap().clone()
}

pub fn get_port_config() -> Option<Arc<RwLock<TcpPorts>>> {
    if let Some(a) = PORT_CONFIG.get().unwrap().as_ref() {
        Some(a.clone())
    } else {
        None
    }
}

pub async fn handle_connection(conn: quinn::Connection) -> anyhow::Result<()> {
    let quic_conn = QuicConn::new(conn);
    let mut stream = QuicConn::accept_bi(quic_conn.clone()).await?;
    let (md, _) = stream.read_metadata().await?;
    let r = md.get_role();
    match r {
        Role::Controlled => {
            let instance = ControlledInstance::new(quic_conn, stream).await;
            tokio::spawn(async move {
                match ControlledInstance::keepalive(instance, md).await {
                    Ok(_) => {}
                    Err(e) => {
                        std::panic::panic_any(e);
                    }
                }
            });
        }
        Role::Client => {}
        Role::Proxy => {
            // 报错
        }
    }
    Ok(())
}
